home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ROCKSVGA.ZIP / ROCKSVGA.PAS < prev   
Pascal/Delphi Source File  |  1994-01-10  |  36KB  |  1,093 lines

  1. {
  2.  XXXXXX    XXXX    XXXXX  XX  XX   XXXXX             by
  3.  XX   XX  XX  XX  XX      XX XX   XX           Paul H. Kahler
  4.  XXXXX    XX  XX  XX      XXXX     XXXX             1993
  5.  XX  XX   XX  XX  XX      XX XX       XX
  6.  XX   XX   XXXX    XXXXX  XX  XX  XXXXX        email: phkahler@oakland.edu
  7. }
  8.          { I am releasing this source code because of numerous requests. }
  9.          { it was never meant to be seen by anyone, as it was thrown }
  10. Program Rocks;     { together in my spare time and is lacking style. }
  11. uses               { The game is good though :)   }
  12.   Crt, Dos, Graph, KeyBoard;
  13.  
  14. Type Number = array[1..7] of byte;
  15.  
  16. var
  17.   GraphDriver : integer;  { The Graphics device driver }
  18.   GraphMode   : integer;  { The Graphics mode value }
  19.   MaxX, MaxY  : word;     { The maximum resolution of the screen }
  20.   ErrorCode   : integer;  { Reports any graphics errors }
  21.   MaxColor    : word;     { The maximum color value available }
  22.   OldExitProc : Pointer;  { Saves exit procedure address }
  23.  
  24.   KBD         : keyboardObj;
  25.   flicker     : word;
  26.   boom        : integer;
  27.   snd,time    : integer;
  28.   freq        :real;
  29.   prvs,soundflag:boolean;
  30.   maxships,rotleft,rotright,fire,thrust,hyper,plop,newgame:byte;
  31.   Ex,Edx,Ey,Edy,Ecount,Etype:integer;
  32.  
  33. {$F+}
  34. VAR
  35.     bl,br:array[0..70] of integer;
  36.     ml,mr:array[0..40] of integer;
  37.     sl,sr:array[0..20] of integer;
  38.     bsl,bsr:array[0..20] of integer;
  39.     smsl,smsr:array[0..10] of integer;
  40.  
  41.     numrocks,RocksLeft :integer;
  42.     NoShip,Color :boolean;
  43.     ssin,scos:real;
  44.     score,high:number;
  45.     shipsleft:integer;
  46.     dustx,dusty,dustcount: array[0..63] of integer;
  47.     numd:integer;
  48.  
  49. procedure INITIALIZE;      { This is right out of the book. }
  50. var                        { Starts up graphics mode }
  51.    Graphdriver:integer;
  52.    Graphmode:integer;
  53.    ErrorCode:integer;
  54. begin
  55.    Graphdriver:=VGA;
  56.    Graphmode:=VGAhi;
  57.    Initgraph(GraphDriver, Graphmode, '');
  58.    ErrorCode:=GraphResult;
  59.    if errorcode <> grOk then begin
  60.      writeln('Graphics error: ',GraphErrorMsg(ErrorCode));
  61.      Writeln('Program aborted...');
  62.      readln;
  63.      Halt(1);
  64.    end;
  65. end;
  66.  
  67. Procedure DrawLetter(l:char; h,v:integer); { Displays a letter }
  68. begin
  69.      case l of
  70.    'a':begin moveto(h,v+20);lineto(h,v+5);lineto(h+3,v);lineto(h+7,v);
  71.              lineto(h+10,v+5);lineto(h+10,v+20);moveto(h,v+12);
  72.              lineto(h+10,v+12);end;
  73.    'b':begin moveto(h+8,v+10);lineto(h+10,v+12);lineto(h+10,v+18);
  74.              lineto(h+8,v+20);lineto(h,v+20);lineto(h,v);lineto(h+8,v);
  75.              lineto(h+10,v+2);lineto(h+10,v+8);lineto(h+8,v+10);
  76.              lineto(h,v+10);end;
  77.    'c':begin moveto(h+10,v);lineto(h+3,v);lineto(h,v+3);lineto(h,v+17);
  78.              lineto(h+3,v+20);lineto(h+10,v+20);end;
  79.    'd':begin moveto(h,v);lineto(h+6,v);lineto(h+10,v+4);lineto(h+10,v+16);
  80.              lineto(h+6,v+20);lineto(h,v+20);lineto(h,v);end;
  81.    'e':begin moveto(h+10,v);lineto(h,v);lineto(h,v+20);lineto(h+10,v+20);
  82.              moveto(h,v+10);lineto(h+7,v+10);end;
  83.    'f':begin moveto(h+10,v);lineto(h,v);lineto(h,v+20);moveto(h,v+10);
  84.              lineto(h+7,v+10);end;
  85.    'g':begin moveto(h+10,v);lineto(h,v);lineto(h,v+20);lineto(h+10,v+20);
  86.              lineto(h+10,v+10);lineto(h+5,v+10);end;
  87.    'h':begin moveto(h,v);lineto(h,v+20);moveto(h+10,v);lineto(h+10,v+20);
  88.              moveto(h,v+10);lineto(h+10,v+10);end;
  89.    'i':begin moveto(h,v);lineto(h+10,v);moveto(h+5,v);lineto(h+5,v+20);
  90.              moveto(h,v+20);lineto(h+10,v+20);end;
  91.    'j':begin moveto(h+10,v);lineto(h+10,v+20);lineto(h,v+20);
  92.              lineto(h,v+15);end;
  93.    'k':begin moveto(h,v);lineto(h,v+20);moveto(h,v+10);lineto(h+5,v+10);
  94.              lineto(h+10,v);moveto(h+5,v+10);lineto(h+10,v+20);end;
  95.    'l':begin moveto(h,v);lineto(h,v+20);lineto(h+10,v+20);end;
  96.    'm':begin moveto(h,v+20);lineto(h,v);lineto(h+5,v+10);lineto(h+10,v);
  97.              lineto(h+10,v+20);end;
  98.    'n':begin moveto(h,v+20);lineto(h,v);lineto(h+10,v+20);lineto(h+10,v);end;
  99.    'o':begin moveto(h,v);lineto(h+10,v);lineto(h+10,v+20);lineto(h,v+20);
  100.              lineto(h,v);end;
  101.    'p':begin moveto(h,v+20);lineto(h,v);lineto(h+10,v);lineto(h+10,v+10);
  102.              lineto(h,v+10);end;
  103.    'q':begin moveto(h,v);lineto(h+10,v);lineto(h+10,v+12);lineto(h+5,v+20);
  104.              lineto(h,v+20);lineto(h,v);moveto(h+6,v+12);lineto(h+10,v+20);
  105.              end;
  106.    'r':begin moveto(h,v+20);lineto(h,v);lineto(h+10,v);lineto(h+10,v+10);
  107.              lineto(h,v+10);moveto(h+5,v+10);lineto(h+10,v+20);end;
  108.    's':begin moveto(h+10,v);lineto(h,v);lineto(h,v+10);lineto(h+10,v+10);
  109.              lineto(h+10,v+20);lineto(h,v+20);end;
  110.    't':begin moveto(h,v);lineto(h+10,v);moveto(h+5,v);lineto(h+5,v+20);end;
  111.    'u':begin moveto(h,v);lineto(h,v+20);lineto(h+10,v+20);lineto(h+10,v);end;
  112.    'v':begin moveto(h,v);lineto(h+5,v+20);moveto(h+10,v);lineto(h+5,v+20);end;
  113.    'w':begin moveto(h,v);lineto(h,v+20);lineto(h+5,v+10);lineto(h+10,v+20);
  114.              lineto(h+10,v);end;
  115.    'x':begin moveto(h,v);lineto(h+10,v+20);moveto(h+10,v);lineto(h,v+20);end;
  116.    'y':begin moveto(h+5,v+20);lineto(h+5,v+10);lineto(h,v);moveto(h+5,v+10);
  117.              lineto(h+10,v);end;
  118.    'z':begin moveto(h,v);lineto(h+10,v);lineto(h,v+20);lineto(h+10,v+20);end;
  119.    end;
  120. end;
  121.  
  122. Procedure DisplayString(s:string; i,j:integer);  { Displays a string }
  123. var c:integer;                                   { at i,j }
  124. begin
  125.      for c:=1 to length(s) do
  126.          DrawLetter(s[c],i-14+c*14,j);
  127. end;
  128.  
  129. Procedure LoadTables;      { loads the collision tables }
  130. var a,i,j:integer;
  131.     f:text;
  132. begin
  133.      assign(f,'Colision.tbl');
  134.      reset(f);
  135.      for a:=0 to 70 do begin      {read big rock colision table}
  136.          readln(f,i,j);
  137.          bl[a]:=i;br[a]:=j;
  138.          end;
  139.      for a:=0 to 40 do begin      {read medium rock colision table}
  140.          readln(f,i,j);
  141.          ml[a]:=i;mr[a]:=j;
  142.          end;
  143.      for a:=0 to 20 do begin      {read small rock colision table}
  144.          readln(f,i,j);
  145.          sl[a]:=i;sr[a]:=j;
  146.          end;
  147.      for a:=0 to 20 do begin      {read big ship colision table}
  148.          readln(f,i,j);
  149.          bsl[a]:=i;bsr[a]:=j;
  150.          end;
  151.      for a:=0 to 10 do begin      {read small ship colision table}
  152.          readln(f,i,j);
  153.          smsl[a]:=i;smsr[a]:=j;
  154.          end;
  155.      close(f);
  156. end;
  157.  
  158. procedure SetRGB(c,r,g,b : byte);  { Set the VGA palette registers }
  159. begin
  160.   port[$03c8]:=c;
  161.   port[$03c9]:=r;
  162.   port[$03c9]:=g;
  163.   port[$03c9]:=b;
  164. end;
  165.  
  166. Procedure SetPalette;               { sets the 10 colors used by rocks }
  167. begin
  168.      SetRGB(0,0,0,0);SetRGB(15,63,63,63);
  169.      SetRGB(1,10,10,63);SetRGB(2,63,0,63);
  170.      SetRGB(3,0,63,10);SetRGB(4,63,63,0);
  171.      SetRGB(5,0,63,50);SetRGB(6,63,10,10);
  172.      SetRGB(7,63,0,32);SetRGB(8,63,32,0);
  173. end;
  174.  
  175. Procedure MoveDust;     { Moves the little explosion particles }
  176. var i:integer;
  177. begin
  178.    for i:=0 to 63 do begin
  179.    if dustcount[i]<20 then begin
  180.      setcolor(0);
  181.      putpixel(dustx[i],dusty[i],0);
  182.      dustx[i]:=dustx[i]+(i and 1)*2-1;
  183.      dusty[i]:=dusty[i]+(i and 2)-1;
  184.      dustcount[i]:=dustcount[i]+1;
  185.      if dustcount[i]<20 then begin
  186.         setcolor(15); putpixel(dustx[i],dusty[i],15); end;
  187.      end;
  188.    end;
  189. end;
  190.  
  191. Procedure MakeDust(x,y:integer);          { Creates an explosion }
  192. begin
  193.   dustx[numd]:=x-4;dusty[numd]:=y;dustcount[numd]:=0;
  194.   dustx[numd+1]:=x+6;dusty[numd+1]:=y;dustcount[numd+1]:=0;
  195.   dustx[numd+2]:=x-4;dusty[numd+2]:=y;dustcount[numd+2]:=0;
  196.   dustx[numd+3]:=x+6;dusty[numd+3]:=y;dustcount[numd+3]:=0;
  197.   dustx[numd+4]:=x;dusty[numd+4]:=y-6;dustcount[numd+4]:=0;
  198.   dustx[numd+5]:=x;dusty[numd+5]:=y-4;dustcount[numd+5]:=0;
  199.   dustx[numd+6]:=x;dusty[numd+6]:=y+6;dustcount[numd+6]:=0;
  200.   dustx[numd+7]:=x;dusty[numd+7]:=y+4;dustcount[numd+7]:=0;
  201.   numd:=(numd+8) and 63;
  202. end;
  203.  
  204. Procedure DrawEnemy(size,x,y:integer);    { Draws the enemy ship }
  205. begin
  206.      case size of
  207.      1:begin
  208.             moveto(x-20,y-1);lineto(x+20,y-1);lineto(x+12,y+10);
  209.             lineto(x-12,y+10);lineto(x-20,y-1);
  210.             moveto(x-12,y-1);lineto(x-5,y-10);lineto(x+5,y-10);
  211.             lineto(x+12,y-1);
  212.        end;
  213.      2:begin
  214.             moveto(x-10,y-1);lineto(x+10,y-1);lineto(x+6,y+5);
  215.             lineto(x-6,y+5);lineto(x-10,y-1);moveto(x-6,y-1);
  216.             lineto(x-2,y-5);lineto(x+2,y-5);lineto(x+6,y-1);
  217.        end;
  218.      end;
  219. end;
  220.  
  221. procedure DrawObject(obtype,x,y:integer);  { Draws an asteroid }
  222. begin
  223.    case obtype of
  224.    1:begin
  225.        MoveTo(x-25,y-18);
  226.        lineTo(x,y-35); lineto(x+15,y-20); lineto(x+25,y-22);
  227.        lineto(x+29,y); lineto(x+20,y+15); lineto(x+25,y+25);
  228.        lineto(x+10,y+35); lineto(x-18,y+32); lineto(x-20,y+20);
  229.        lineto(x-29,y+5); lineto(x-25,y-18);
  230.        end;
  231.    2:begin
  232.        MoveTo(x,y-20); lineto(x+10,y-15);
  233.        lineTo(x+5,y-5); lineto(x+13,y-5);
  234.        lineto(x+20,y+5); lineto(x+5,y+20);
  235.        lineto(x-15,y+15); lineto(x-20,y);
  236.        lineto(x-10,y-15); lineto(x,y-20);
  237.        end;
  238.    3:begin
  239.        Moveto(x,y-10); lineto(x+7,y-5);
  240.        lineto(x+10,y+5); lineto(x+3,y+10);
  241.        lineto(x-8,y+8); lineto(x-10,y);
  242.        lineto(x-5,y-10); lineto(x,y-10);
  243.        end;
  244.    end;
  245. end;
  246.  
  247. procedure rotmove(i,j,x,y,s,c:real);       { like 'move' but with rotation }
  248. var h,v:real;
  249. begin
  250.      moveto(round(i+c*x+s*y),round(j+s*x-c*y));
  251. end;
  252.  
  253. procedure rotline(i,j,x,y,s,c:real);       { like 'line' but with rotation }
  254. var h,v:real;
  255. begin
  256.      lineto(round(i+c*x+s*y),round(j+s*x-c*y));
  257. end;
  258.  
  259. Procedure DrawShip(x,y,flame:real);      { Draws the players ship }
  260. VAR s,c,h,v,ex:real;
  261.  
  262. begin
  263.      s:=-ssin; c:=scos;
  264.      if boom=0 then begin
  265.        rotmove(x,y,-10,10,s,c);
  266.        rotline(x,y,18,0,s,c); rotline(x,y,-10,-10,s,c);
  267.        rotline(x,y,-8,-8,s,c); rotline(x,y,-6,-4,s,c);
  268.        rotline(x,y,-5,0,s,c); rotline(x,y,-6,4,s,c);
  269.        rotline(x,y,-8,8,s,c); rotline(x,y,-10,10,s,c);
  270.        if (flame>0) and (flicker>0) then begin
  271.           rotmove(x,y,-7,5,s,c);
  272.           rotline(x,y,-10-flame,0,s,c);
  273.           rotline(x,y,-7,-5,s,c);
  274.           end;
  275.        flicker:= (flicker+1) and 3;
  276.        end
  277.      else begin           { Draws the players ship exploding }
  278.        ex:=boom/10;
  279.        rotmove(x,y,-10+ex,-10+ex,s,c);rotline(x,y,-8+ex,-7+ex,s,c);
  280.        rotmove(x,y,-10-ex,10-ex,s,c);rotline(x,y,-8-ex*1.01,7-ex,s,c);
  281.        rotmove(x,y,-7+ex*2,7-ex,s,c);rotline(x,y,-7+ex*1.8,-7+ex,s,c);
  282.        rotmove(x,y,-10,10+ex,s,c);rotline(x,y,4,5+ex*1.5,s,c);
  283.        rotmove(x,y,4+ex,5+ex,s,c);rotline(x,y,18+ex,ex*2,s,c);
  284.        rotmove(x,y,4,-5+ex*0.2,s,c);rotline(x,y,18+ex*0.2,-ex,s,c);
  285.        rotmove(x,y,-10-ex*0.2,-10-ex,s,c);rotline(x,y,4-ex,-5-ex,s,c);
  286.        end;
  287. end;
  288.  
  289. var x,y,dx,dy,kind:array[1..100] of integer;
  290.     a:integer;
  291.     angle,sx,sy,dsx,dsy,v2:real;
  292.     flame,oflame:real;
  293.     shotflag:boolean;
  294.     numshots:integer;
  295.     shf: array[1..5] of boolean;
  296.     shx,shy,shdx,shdy: array[1..5] of real;
  297.     shtime: array[1..5] of integer;
  298.     level,digit:integer;
  299.     oldtime:byte;
  300.     scoreflag,highflag,dead:boolean;
  301.     hypcount:integer;
  302.  
  303. Procedure miniship(h,v:integer);        { Draws the ships-left ship }
  304. begin
  305.      line(h+5,0,h,15);
  306.      line(h+5,0,h+10,15);
  307.      line(h+10,15,h+5,12);line(h+5,12,h,15);
  308. end;
  309.  
  310. Procedure KillRock(r:integer);    { Destroys a rock, creates small one }
  311. var i:integer;                    { and throws in some dust }
  312. begin
  313.      setcolor(0); DrawObject(kind[r],x[r] div 2,y[r] div 2);
  314.      If snd<4 then begin
  315.         snd:=3; time:=30;
  316.         end;
  317.      MakeDust(x[r] div 2,y[r] div 2);
  318.      kind[r]:=(kind[r]+1) and 3;
  319.      if kind[r]>0 then begin
  320.        i:=numrocks+1; numrocks:=i;
  321.        kind[i]:=kind[r]; x[i]:=x[r]; y[i]:=y[r];
  322.        dx[r]:=0; dy[r]:=0;
  323.        case kind[r] of
  324.        2:begin
  325.               while dx[r]=0 do dx[r]:=random(7)-3;
  326.               while dy[r]=0 do dy[r]:=random(7)-3;
  327.               end;
  328.        3:begin
  329.               while dx[r]=0 do dx[r]:=random(9)-5;
  330.               while dy[r]=0 do dy[r]:=random(9)-5;
  331.               end;
  332.        end;
  333.        dx[i]:=-dx[r];
  334.        dy[i]:=-dy[r];
  335.        end;
  336.        RocksLeft:=RocksLeft-1;
  337.        if RocksLeft=0 then level:=level+1;
  338. end;
  339.  
  340. Procedure KillEnemy;    { Destroys enemy ship/ makes dust }
  341. begin
  342.      Setcolor(0);
  343.      DrawEnemy(Etype,Ex,Ey);
  344.      SND:=3;time:=20;
  345.      MakeDust(Ex-15,Ey+5);MakeDust(Ex-3,Ey-4);
  346.      MakeDust(Ex+6,Ey+9);MakeDust(Ex,Ey);
  347.          Ex:=700;
  348.      if RocksLeft<0 then RocksLeft:=-50;
  349.      Snd:=10;Time:=0;
  350. end;
  351.  
  352. Function HitEnemy(h,v:integer):boolean;
  353. var i,j:integer;
  354.     edead:boolean;              { Checks for colision of enemy with the }
  355. begin                           { point (h,v). }
  356.      edead:=false;
  357.     if Ecount>0 then begin
  358.        i:=h-Ex; j:=v-Ey;
  359.        case Etype of
  360.         1:if (abs(i)<21) and (abs(j)<11) then
  361.              if (i>=bsl[j+10]) and (i<=bsr[j+10]) then edead:=true;
  362.         2:if (abs(i)<15) and (abs(j)<6) then
  363.              if (i>=smsl[j+5]) and (i<=smsr[j+5]) then edead:=true;
  364.        end;
  365.        end;
  366.      HitEnemy:=edead;
  367. end;
  368.  
  369. Function ColisionDetect(h,v:integer):integer;
  370. var i,j,rock,cr:integer;
  371.     done:boolean;         { Returns the number of the rock hit at (h,v) }
  372. begin                     { or 0 if no rock hit }
  373.      done:=false;
  374.      rock:=1;
  375.      cr:=0;
  376.      while (rock<=numrocks) and (not done) do begin
  377.         if kind[rock]>0 then begin
  378.            i:=h-(x[rock] div 2); j:=v-(y[rock] div 2);
  379.            case kind[rock] of
  380.              1:if (abs(i)<31) and (abs(j)<36) then
  381.                 if (i>=bl[j+35]) and (i<=br[j+35]) then begin
  382.                  done:=true;
  383.                  cr:=rock;
  384.                  end;
  385.              2:if (abs(i)<21) and (abs(j)<22) then
  386.                 if(i>=ml[j+20]) and (i<=mr[j+20]) then begin
  387.                  done:=true;
  388.                  cr:=rock;
  389.                  end;
  390.              3:if (abs(i)<11) and (abs(j)<11) then
  391.                 if(i>=sl[j+10]) and (i<=sr[j+10]) then begin
  392.                  done:=true;
  393.                  cr:=rock
  394.                  end;
  395.            end;
  396.            end;
  397.            rock:=rock+1;
  398.         end;
  399.         ColisionDetect:=cr;
  400. end;
  401.  
  402. Procedure HitShip;      { Determines if the enemy bullet hits the player }
  403. var i,j,t:real;         { by rotating the point WRT the ship and comparing }
  404. begin                   { with 2 lines. (don't ask) }
  405.      i:=sx-shx[5];j:=sy-shy[5];
  406.      if (abs(i)<20) and (abs(j)<20) then begin
  407.         t:=i;
  408.         i:=-scos*i+ssin*j;
  409.         j:=abs(ssin*t+scos*j);
  410.         if (j<(6.42857-0.35714*i)) and (j>(-2*i-10)) then begin
  411.            setcolor(0); DrawShip(sx,sy,flame);
  412.            boom:=1; dsx:=dsx*0.2; dsy:=dsy*0.2;
  413.            snd:=10;time:=0;
  414.            shtime[5]:=160;
  415.            end;
  416.      end;
  417. end;
  418.  
  419. Procedure Shoot;     { Handles player shots and a bunch more }
  420. var s,c:real;        { Should have broken this down more }
  421.     i,j,r:integer;
  422. begin
  423.      if KBD.Down(fire) and (not shotflag) and
  424.         (numshots < 4) and (not NoShip) and (boom=0) then begin
  425.            if snd<3 then begin
  426.              snd:=2; freq:=10000; time:=15;
  427.              end;
  428.            a:=1;
  429.            while shf[a] do a:=a+1;
  430.            shx[a]:=sx+16*scos; shy[a]:=sy-16*ssin;
  431.            shdx[a]:=dsx+scos*2.5; shdy[a]:=dsy-ssin*2.5;
  432.            shtime[a]:=0; shf[a]:=true;
  433.            shotflag:=true;
  434.            numshots:=numshots+1;
  435.            end;
  436.      if not KBD.Down(fire) then shotflag:=false;
  437.      for a:=1 to 5 do
  438.      if shf[a] then begin
  439.       setcolor(0);
  440.       i:=round(shx[a]); J:=round(shy[a]);
  441.         line(i-1,j,i+1,j);
  442.         line(i,j-1,i,j+1);
  443.       shx[a]:=shx[a]+shdx[a]; shy[a]:=shy[a]+shdy[a];
  444.       if shx[a]<0 then shx[a]:=640
  445.         else if shx[a]>640 then shx[a]:=0;
  446.       if shy[a]<0 then shy[a]:=480
  447.         else if shy[a]>480 then shy[a]:=0;
  448.       shtime[a]:=shtime[a]+1;
  449.       if shtime[a]>110 then begin shf[a]:=false;if a<5 then
  450.                                   numshots:=numshots-1;end;
  451.       if shf[a] then begin
  452.         setcolor(15);
  453.         i:=round(shx[a]); J:=round(shy[a]);
  454.         line(i-1,j,i+1,j);
  455.         line(i,j-1,i,j+1);
  456.         r:=ColisionDetect(i,j);
  457.         if r>0 then begin
  458.           if a<5 then begin
  459.               case kind[r] of
  460.                 1:score[6]:=score[6]+2;  {add score for different size rox}
  461.                 2:score[6]:=score[6]+5;
  462.                 3:score[6]:=score[6]+9;
  463.                 end;
  464.               i:=6;
  465.               while score[i]>9 do begin
  466.                     score[i]:=score[i]-10;
  467.                     if i>1 then begin i:=i-1; score[i]:=score[i]+1; end;
  468.               if i<4 then shipsleft:=shipsleft+1;
  469.               end;
  470.         end;
  471.  
  472.           KillRock(r);
  473.           shtime[a]:=160;
  474.           end;
  475.         end;
  476.         if a<5 then begin
  477.           If HitEnemy(i,j) then begin
  478.             KillEnemy;
  479.             Score[5]:=Score[5]+Etype;
  480.             r:=5;
  481.             while (r>0) and (Score[r]>9) do begin
  482.               Score[r]:=Score[r]-10;
  483.               r:=r-1;
  484.               Score[r]:=Score[r]+1;
  485.               if r<4 then ShipsLeft:=ShipsLeft+1;
  486.               end;
  487.             shtime[a]:=160;
  488.             end;
  489.           end;
  490.      end;
  491.      if shf[5] and (boom=0) and not NoShip then HitShip;
  492. end;
  493.  
  494. Procedure NewRocks;             { Creates a new asteroid field }
  495. begin
  496.   NumRocks:=4+(level div 2);
  497.   if NumRocks>8 then NumRocks:=8;
  498.   RocksLeft:=7*NumRocks;
  499.   Ecount:=-1000-200*NumRocks;
  500.   for a:=1 to 100 do begin
  501.   kind[a]:=0; if a<=NumRocks then begin
  502.     kind[a]:=1;
  503.     x[a]:=320; y[a]:=240;
  504.     while (x[a]>240) and (x[a]<1000) and (y[a]>160) and (y[a]<760) do
  505.        begin
  506.        x[a]:=random(1280);
  507.        y[a]:=random(960);
  508.        end;
  509.     dx[a]:=((a and 1)*2-1)*(((a-1) and 4)div 4 +1);
  510.     dy[a]:=(a and 2)-1;
  511.     end;
  512.   end;
  513. end;
  514.  
  515. Procedure MoveRocks;    { Updates the rocks for one frame }
  516. begin
  517.    If RocksLeft > 0 then begin
  518.    for a:=1 to numrocks do begin
  519.      setcolor(0);                        { erase object }
  520.      drawobject(kind[a],x[a] div 2,y[a] div 2);
  521.      x[a]:=x[a]+dx[a];                   { move object }
  522.      y[a]:=y[a]+dy[a];
  523.      if x[a] > 1310 then x[a]:=x[a]-1310;  { horizontal wrap around }
  524.      if x[a] < -20 then x[a]:=x[a]+1310;
  525.      if y[a] >1000 then y[a]:=y[a]-1040;   { vertical wrap around }
  526.      if y[a] <-20 then y[a]:=y[a]+1040;
  527.      if color then setcolor((a and 7)+1) else setcolor(15);
  528.      drawobject(kind[a],x[a] div 2,y[a] div 2);  { draw in new position }
  529.      end;
  530.      end
  531.    else begin
  532.       RocksLeft:=RocksLeft-1;
  533.       If (RocksLeft<-200) and (Ecount<0) then NewRocks;
  534.       end;
  535. end;
  536.  
  537. procedure MoveShip;     { Handles player ship movement and more }
  538. begin                   { This procedure got WAY out of hand :) }
  539.   if NoShip then begin
  540.     if hypcount=0 then begin
  541.        NoShip:=false;
  542.        sx:=320; sy:=240;
  543.        dsx:=0; dsy:=0; angle:=1.57;
  544.        ssin:=1; scos:=0;
  545.        flicker:=1;
  546.        if (Ecount>0) or shf[5] then NoShip:=True;
  547.        for a:=1 to numrocks do begin
  548.          if (kind[a]>0) then
  549.            if (x[a]<960) and (x[a]>320) and (y[a]<760) and (y[a]>220) then
  550.            NoShip:=true;
  551.          end;
  552.        if KBD.Down(plop) then NoShip:=false;
  553.        if not NoShip then begin
  554.          setcolor(0);
  555.          miniship(14*shipsleft,0);
  556.          Shipsleft:=ShipsLeft-1;
  557.          end;
  558.     end;
  559.    if hypcount>0 then begin      { if ship is in hyperspace, hypcount }
  560.         hypcount:=hypcount-1;    { will be greater than zero }
  561.         if hypcount=0 then begin {bring ship out of hyperspace}
  562.           sx:=random(600)+20; dsx:=0;
  563.           sy:=random(440)+20; dsy:=0;
  564.           flicker:=1;
  565.           noship:=false;
  566.           if Random(3)=0 then begin
  567.              boom:=1;
  568.              Snd:=10;time:=0;
  569.              end;
  570.           end;
  571.         end;
  572.    end
  573.   else begin
  574.    if (boom=0) and KBD.Down(thrust) then begin
  575.           dsx:=dsx+scos*0.05;
  576.           dsy:=dsy-ssin*0.05;
  577.           if flame < 10 then flame:=flame+0.5;
  578.           if snd=0 then begin snd:=1; time:=1; end;
  579.           end
  580.       else flame:=0;
  581.    V2:=(dsx*dsx+dsy*dsy)*0.0005;
  582.    dsx:=dsx*(0.997-v2);
  583.    dsy:=dsy*(0.997-v2);
  584.    setcolor(0);drawship(sx,sy,oflame);
  585.      if boom>0 then begin
  586.           boom:=boom+1;
  587.           if boom=120 then begin
  588.             boom:=0;
  589.             Noship:=true;
  590.             if shipsleft=0 then shipsleft:=-1;
  591.             end;
  592.           end;
  593.    If KBD.Down(rotleft) and (boom=0) then begin
  594.       angle:=angle+0.05;
  595.       if angle > 6.283185 then angle:=angle - 6.283185;
  596.       end;
  597.    if KBD.Down(rotright) and (boom=0) then begin
  598.       angle:=angle-0.05;
  599.       if angle < 0 then angle:=angle + 6.283185;
  600.       end;
  601.    ssin:=sin(angle); scos:=cos(angle);
  602.      sx:=sx+dsx; sy:=sy+dsy;
  603.    if sx > 660 then sx:=sx-680;  { horizontal wrap around }
  604.    if sx < -20 then sx:=sx+680;
  605.    if sy >500 then sy:=sy-520;   { vertical wrap around }
  606.    if sy <-20 then sy:=sy+520;
  607.   if not NoShip then begin
  608.      setcolor(15);drawship(sx,sy,flame);end;
  609.   oflame:=flame;
  610.   end;
  611. end;
  612.  
  613. Procedure Crash;   { Tests 5 points on the ship for colision with }
  614. var i,j:integer;   { Asteroids and enemy ships }
  615.     s,c:real;
  616. begin
  617.    if (not NoShip) and (boom=0) then begin
  618.    dead:=false;
  619.    i:=round(sx-scos*10+ssin*10);
  620.    j:=round(sy+ssin*10+scos*10);
  621.      if ColisionDetect(i,j)>0 then dead:=true;
  622.      if HitEnemy(i,j) then begin
  623.         dead:=true;
  624.         KillEnemy;
  625.         end;
  626.    i:=round(sx+scos*4-ssin*5);
  627.    j:=round(sy-ssin*4-scos*5);
  628.      if ColisionDetect(i,j)>0 then dead:=true;
  629.      if HitEnemy(i,j) then begin
  630.         dead:=true;
  631.         KillEnemy;
  632.         end;
  633.    i:=round(sx+scos*4+ssin*5);
  634.    j:=round(sy-ssin*4+scos*5);
  635.      if ColisionDetect(i,j)>0 then dead:=true;
  636.      if HitEnemy(i,j) then begin
  637.         dead:=true;
  638.         KillEnemy;
  639.         end;
  640.    i:=round(sx-scos*10-ssin*10);
  641.    j:=round(sy+ssin*10-scos*10);
  642.      if ColisionDetect(i,j)>0 then dead:=true;
  643.      if HitEnemy(i,j) then begin
  644.         dead:=true;
  645.         KillEnemy;
  646.         end;
  647.    i:=round(sx+scos*18);
  648.    j:=round(sy-ssin*18);
  649.      if ColisionDetect(i,j)>0 then dead:=true;
  650.      if HitEnemy(i,j) then begin
  651.         KillEnemy;
  652.         dead:=true;
  653.         end;
  654.    if dead then begin
  655.       setcolor(0); DrawShip(sx,sy,flame);
  656.       boom:=1; dsx:=dsx*0.2; dsy:=dsy*0.2;
  657.       Snd:=10;time:=0;
  658.       end;
  659.    end;
  660. end;
  661.  
  662. Procedure DisplayNumber(d,h,v:integer);      { Displays a digit }
  663. begin
  664.      setcolor(0);line(h,v,h+10,v);line(h,v,h,v+20);line(h+10,v,h+10,v+20);
  665.      line(h,v+10,h+10,v+10);line(h,v+20,h+10,v+20);
  666.      setcolor(15);
  667.      if (d=0) or (d=1) or (d=3) or (d=4) or (d>6) then
  668.            line(h+10,v,h+10,v+20);
  669.      if (d <> 1) and (d <> 4) then line(h,v,h+10,v);
  670.      if (d <> 0) and (d <> 1) and (d <> 7) then line(h,v+10,h+10,v+10);
  671.      if (d <> 1) and (d <> 4) and (d <> 7) then line(h,v+20,h+10,v+20);
  672.      if (d = 0) or (d = 6) or (d = 8) then line(h,v,h,v+20);
  673.      if d=2 then begin line(h+10,v,h+10,v+10);line(h,v+10,h,v+20);end;
  674.      if (d=4) or (d=5) or (d=6) or (d=9) then begin
  675.              line(h,v,h,v+10);line(h+10,v+10,h+10,v+20);end;
  676. end;
  677.  
  678. Procedure EShoot;    { Handles enemy fire }
  679. var t:real;
  680. begin
  681.      case Etype of
  682.      1:begin
  683.             shdx[5]:=0;shdy[5]:=0;
  684.             while (abs(shdx[5])+abs(shdy[5]))<2.5 do begin
  685.                   shdx[5]:=random(40)/10-2;
  686.                   shdy[5]:=random(40)/10-2;
  687.                   end;
  688.             shtime[5]:=0;
  689.             shx[5]:=Ex+4*shdx[5];
  690.             shy[5]:=Ey+4*shdy[5];
  691.             shf[5]:=true;
  692.        end;
  693.      2:begin
  694.             t:=160;shdx[5]:=0;shdy[5]:=0;
  695.             while ((abs(shdx[5])+abs(shdy[5]))<3) and (t>10) do begin
  696.                 t:=t-10;
  697.                 shdx[5]:=(sx+dsx*t*0.9-Ex)/t;
  698.                 shdy[5]:=(sy+dsy*t*0.9-Ey)/t;
  699.                 end;
  700.             shx[5]:=Ex+2*shdx[5];
  701.             shy[5]:=Ey+2*shdy[5];
  702.             shtime[5]:=0;
  703.             shf[5]:=true;
  704.        end;
  705.      end;
  706. end;
  707.  
  708. Procedure MoveEnemy;      { Handles emeny movement }
  709. var r:integer;
  710.     f:boolean;
  711. begin
  712.      if Ecount<0 then Ecount:=Ecount+1;
  713.      if Ecount=0 then begin
  714.           f:=true;
  715.           for r:=1 to NumRocks do
  716.           if kind[r]>0 then
  717.             if ((x[r]<150) or (x[r]>500)) and (y[r]<Ey+80) and (y[r]>Ey-80)
  718.                then f:=false;
  719.           if f then begin
  720.              Ecount:=Ecount+1;
  721.              If Snd<7 then Snd:=6+Etype;
  722.              end;
  723.         end;
  724.      if Ecount>0 then begin
  725.         if (Ex and 127)= 63 then EShoot;
  726.         SetColor(0);DrawEnemy(Etype,Ex,Ey);  {moveship}
  727.         Ex:=Ex+Edx;Ey:=Ey+Edy;
  728.         SetColor(15);DrawEnemy(Etype,Ex,Ey);
  729.         If (Ey>460) or (Ey<20) then Edy:=0;  {Check Vertical bounds}
  730.         If Random(100)=4 then begin           {Make course change}
  731.            Edy:=random(3)-1;
  732.            if Ey>400 then Edy:=-1;
  733.            if Ey<80 then Edy:=1;
  734.            end;
  735.         If (Ex>660) or (Ex<-20) then begin
  736.            if Snd<9 then Snd:=0;
  737.            Ecount:=-600-Random(500);
  738.            Etype:=1;
  739.            if random(3+level)>3 then Etype:=2;
  740.            Ey:=random(400)+40;
  741.            Edy:=random(3)-1;
  742.            Ex:=600;Edx:=-1;
  743.            if random(2)=0 then begin
  744.               Ex:=-20;Edx:=1;
  745.               end;
  746.            end;
  747.      end;
  748. end;
  749.  
  750. Procedure CrashEnemy;    { Checks for enemy/rock colisions }
  751. begin
  752.      if Etype=1 then
  753.         If (ColisionDetect(Ex-20,Ey-1)>0) or (ColisionDetect(Ex+20,Ey-1)>0)
  754.         or (ColisionDetect(Ex-12,Ey+10)>0) or (ColisionDetect(Ex+12,Ey+10)>0)
  755.         or (ColisionDetect(Ex-5,Ey-10)>0) or (ColisionDetect(Ex+5,Ey-10)>0)
  756.           then KillEnemy;
  757.      if Etype=2 then
  758.         If (ColisionDetect(Ex-10,Ey-1)>0) or (ColisionDetect(Ex+10,Ey-1)>0)
  759.         or (ColisionDetect(Ex-6,Ey+5)>0) or (ColisionDetect(Ex+6,Ey+5)>0)
  760.         or (ColisionDetect(Ex-2,Ey-5)>0) or (ColisionDetect(Ex+2,Ey-5)>0)
  761.           then KillEnemy;
  762. end;
  763.  
  764. Procedure StartScreen;   { Displays the startup screen }
  765. var h,c,l:word;
  766. begin
  767.    ClearDevice;
  768.    setcolor(15);
  769.    moveto(110,160);lineto(110,60);lineto(170,60);lineto(170,110);
  770.    lineto(110,110);moveto(140,110);lineto(170,160);
  771.    moveto(200,60);lineto(260,60);lineto(260,160);lineto(200,160);
  772.    lineto(200,60);
  773.    moveto(350,60);lineto(290,60);lineto(290,160);lineto(350,160);
  774.    moveto(380,60);lineto(380,160);moveto(380,110);lineto(410,110);
  775.    lineto(440,60);moveto(410,110);lineto(440,160);
  776.    moveto(530,60);lineto(470,60);lineto(470,110);lineto(530,110);
  777.    lineto(530,160);lineto(470,160);
  778.    DisplayString('copyright',261,220);
  779.    DisplayString('by',309,280);
  780.    h:=230;c:=15;
  781.    for l:=1 to 4 do begin                  { A crude way to encode my }
  782.        DrawLetter(chr(c+ord('a')),h,310);  { name so it doesn't appear }
  783.        h:=h+14;                            { in the .exe file. }
  784.        c:=(c*34+20) mod 53;
  785.        end;
  786.    h:=328;c:=10;
  787.    for l:=1 to 4 do begin
  788.        DrawLetter(chr(c+ord('a')),h,310);
  789.        h:=h+14;
  790.        c:=(c*26+7) mod 89;
  791.        end;
  792.    DisplayString('h     er',300,310);
  793.    DisplayNumber(1,287,250);DisplayNumber(9,303,250);
  794.    DisplayNumber(9,317,250);DisplayNumber(3,331,250);
  795.    DisplayString('f  for help',244,450); DisplayNumber(1,254,450);
  796.    mem[$0040:$006c]:=0;
  797.    while mem[$0040:$006c]<80 do ;
  798. end;
  799.  
  800. Procedure ShowScores;   { Only one digit of each score is displayed each }
  801. begin                   { frame. Don't need rapid update }
  802.      Digit:=Digit+1;if digit=8 then begin
  803.          digit:=1;scoreflag:=false;highflag:=false;end;
  804.      if (score[digit]>0) or (digit=7) then scoreflag:=true;
  805.      if (high[digit]>0) or (digit=7) then highflag:=true;
  806.      if scoreflag then DisplayNumber(Score[digit],480+digit*14,0);
  807.      if highflag then DisplayNumber(high[digit],220+digit*14,0);
  808.      if shipsleft>=digit then begin
  809.         setcolor(15); miniship(14*digit,0); end;
  810. end;
  811.  
  812. Procedure PlaySound;    { This procedure is responsible for creating all }
  813. var tone:word;          { the cheap sound effects. I should have made a }
  814. begin                   { Startsound procedure too to keep things nice }
  815.      if KBD.Down(kS) then begin
  816.           if prvs then soundflag:=not soundflag;
  817.           if not soundflag then nosound;
  818.           snd:=0;
  819.           prvs:=false;
  820.           end
  821.         else prvs:=true;
  822.    if soundflag then
  823.      case snd of
  824.        0:NoSound;
  825.        1:begin
  826.           if time=0 then begin
  827.              NoSound; snd:=0; end
  828.           else begin
  829.                time:=0;
  830.                if random(5)=0 then NoSound
  831.                   else Sound(Random(50)+60);
  832.                end;
  833.          end;
  834.        2:begin
  835.           if time=0 then begin
  836.              NoSound; snd:=0; end
  837.           else begin
  838.             time:=time-1;
  839.             tone:=round(freq);
  840.             sound(tone);
  841.             freq:=(freq*0.7);
  842.             end;
  843.          end;
  844.        3:begin
  845.               if time=0 then begin
  846.                  NoSound; snd:=0; end
  847.               else begin
  848.                    time:=time-1;
  849.                    sound(random(70+time));
  850.                    end;
  851.          end;
  852.        7:begin
  853.               freq:=freq*1.05;
  854.               if freq>3500 then freq:=1500;
  855.               tone:=round(freq);
  856.               sound(tone);
  857.          end;
  858.        8:begin
  859.               freq:=freq*1.1;
  860.               if freq>5000 then freq:=2500;
  861.               tone:=round(freq);
  862.               sound(tone);
  863.          end;
  864.        10:begin
  865.                if time<100 then begin
  866.                   time:=time+1;
  867.                   if random(10)=0 then NoSound
  868.                      else
  869.                      sound(random(200-time))
  870.                   end
  871.                   else begin snd:=0; nosound; end;
  872.           end;
  873.      end;
  874. end;
  875.  
  876. Procedure LoadOptions;   { Loads the saved settings (mostly key values) }
  877. var f:text;
  878.     c:integer;
  879. begin
  880.    assign(f,'rockdata');
  881.    reset(f);
  882.    readln(f,rotleft);
  883.    readln(f,rotright);
  884.    readln(f,fire);
  885.    readln(f,thrust);
  886.    readln(f,hyper);
  887.    readln(f,plop);
  888.    readln(f,newgame);
  889.    readln(f,maxships);
  890.    readln(f,c);
  891.    close(f);
  892.    color:=false;
  893.    if c=1 then color:=true;
  894. end;
  895.  
  896. Procedure SaveOptions;     { Saves the options }
  897. var f:text;
  898. begin
  899.    Port[$43] := $43;  {restore normal timer frequency}
  900.    Port[$40] := 0;    {this has to be done to read/write disks}
  901.    Port[$40] := 0;
  902.    setcolor(15);
  903.    DisplayString('saving',264,380);
  904.    oldtime:=mem[$0040:$006c];   {wait for clock to be normal}
  905.      while mem[$0040:$006c]=oldtime do ;
  906.    assign(f,'rockdata');
  907.    rewrite(f);
  908.    writeln(f,rotleft);
  909.    writeln(f,rotright);
  910.    writeln(f,fire);
  911.    writeln(f,thrust);
  912.    writeln(f,hyper);
  913.    writeln(f,plop);
  914.    writeln(f,newgame);
  915.    writeln(f,maxships);
  916.    if color then writeln(f,1)
  917.             else writeln(f,0);
  918.    close(f);
  919.    mem[$0040:$006c]:=0;
  920.    while mem[$0040:$006c]<90 do ;
  921.    setcolor(0);
  922.    DisplayString('saving',264,380);
  923.    Port[$21]:=Port[$21] and $FE; {alter interupt freq again}
  924.    Port[$43]:=$43;
  925.    Port[$40]:=0;
  926.    Port[$40]:=60;
  927. end;
  928.  
  929. Function WhichKey:byte;    { Waits for a keypress. I think this is the }
  930. var k:byte;                { cause of the help-screen lockup bug. I think }
  931. begin                      { some of the invalid codes get set to Down }
  932.    k:=0;                   {and never go up (since they aren't really keys)}
  933.    while not KBD.Down(k) do begin   { If you find a simple fix, let me know}
  934.          k:=k+1;
  935.          if k=160 then k:=176;
  936.          if k=128 then k:=144;
  937.          if k=240 then k:=0;
  938.          end;
  939.    while KBD.Down(k) do ;
  940.    WhichKey:=k;
  941. end;
  942.  
  943. Function GetDef(functn:string):byte;  { Waits for user to select a key for }
  944. begin                                 { various functions }
  945.    Setcolor(15);
  946.    DisplayString(functn,325,380);
  947.    GetDef:=WhichKey;
  948.    Setcolor(0);
  949.    DisplayString(functn,325,380);
  950. end;
  951.  
  952. Procedure DefineKeys;                 { Prompts player for each key }
  953. begin
  954.    Setcolor(4);
  955.    DisplayString('choose key to',130,380);
  956.    fire:=Getdef('fire');
  957.    thrust:=Getdef('thrust');
  958.    rotleft:=Getdef('rotate left');
  959.    rotright:=Getdef('rotate right');
  960.    hyper:=Getdef('hyperspace');
  961.    plop:=Getdef('force next ship');
  962.    newgame:=Getdef('start new game');
  963.    SetColor(0);
  964.    DisplayString('choose key to',130,380);
  965. end;
  966.                 
  967. Procedure Help;          { Displays the help screen }
  968. var k:byte;
  969.     temps,tempc:real;
  970. begin
  971.    NoSound;
  972.    ClearDevice;
  973.    SetColor(15);
  974.    DisplayString('rocks help screen',194,0);
  975.    SetColor(1);
  976.    DisplayString('while playing press',180,40);
  977.    SetColor(4);
  978.    DisplayString('b for black and white',180,70);
  979.    DisplayString('c for color',180,100);
  980.    DisplayString('s to toggle sound',180,130);
  981.    SetColor(2);
  982.    DisplayString('plus or minus to change ships per game',54,260);
  983.    SetColor(7);
  984.    DisplayString('press r to redefine ship controls',96,290);
  985.    DisplayString('s to save settings',180,320);
  986.    Setcolor(6);
  987.    DisplayString('   escape to exit help screen',96,455);
  988.    repeat
  989.       temps:=ssin;tempc:=scos;
  990.       ssin:=1;scos:=0;
  991.       For k:=1 to 8 do begin
  992.          Setcolor(15);
  993.          if k>maxships then SetColor(0);
  994.          DrawShip(180+30*k,210,0);
  995.          end;
  996.       ssin:=temps;scos:=tempc;
  997.       k:=WhichKey;
  998.       if (k=12) and (maxships>1) then maxships:=maxships-1;
  999.       if (k=13) then maxships:=maxships+1;
  1000.       if k=19 then DefineKeys;
  1001.       if k=31 then SaveOptions;
  1002.    until k=1;
  1003.    ClearDevice;
  1004. end;
  1005.  
  1006. begin {main}
  1007.    {Initialize}
  1008.    LoadTables;
  1009.    LoadOptions;
  1010.    for a:=1 to 7 do high[a]:=0; {clear high score}
  1011.    INITIALIZE;
  1012.    SetPalette;
  1013.    StartScreen;
  1014.    KBD.INIT;
  1015.    MaxShips:=4;
  1016.    numd:=0;
  1017.    for a:=0 to 63 do dustcount[a]:=20;
  1018.    Randomize;
  1019.    Port[$21]:=Port[$21] and $FE; {alter interupt freq}
  1020.    Port[$43]:=$43;               { The timer frequency is changed and used }
  1021.    Port[$40]:=0;                 { as a speed limiter }
  1022.    Port[$40]:=60;
  1023.    soundflag:=false;
  1024. repeat
  1025.    {begin game}
  1026.    ClearDevice;
  1027.    NoSound; Snd:=0;
  1028.    ssin:=1;scos:=0;
  1029.    dsx:=0; dsy:=0; flame:=0; oflame:=0; flicker:=1; boom:=0;
  1030.    hypcount:=0;
  1031.    for a:=1 to 5 do begin
  1032.        shx[a]:=0;shy[a]:=0;shdx[a]:=0;shdy[a]:=0;
  1033.        shf[a]:=false;
  1034.        shtime[a]:=0;
  1035.        end;
  1036.    numshots:=0;
  1037.    level:=1;
  1038.    shipsleft:=MaxShips;
  1039.    for a:=1 to 7 do score[a]:=0;
  1040.    digit:=0; scoreflag:=false; highflag:=false;
  1041.    numrocks:=-100;
  1042.    RocksLeft:=0;
  1043.    NoShip:=true;
  1044.    Ex:=700;Edx:=1;Ey:=99;Edy:=1;Etype:=1;
  1045.    Ecount:=-1000;
  1046.    {********** MAIN GAME LOOP ***********}
  1047.    repeat
  1048.      if KBD.Down(kC) then color:=true;
  1049.      if KBD.Down(kB) then color:=false;
  1050.      if KBD.Down(hyper) and (boom=0) and (not NoShip) then begin
  1051.         SetColor(0);
  1052.         DrawShip(sx,sy,flame);
  1053.         hypcount:=50;
  1054.         NoShip:=True;
  1055.         end;
  1056.      Moverocks;
  1057.      MoveShip;
  1058.      MoveEnemy;
  1059.      Shoot;
  1060.      Crash;
  1061.      If Ecount>0 then CrashEnemy;
  1062.      MoveDust;
  1063.      ShowScores;
  1064.      PlaySound;
  1065.      while mem[$0040:$006c]=oldtime do ;  { wait for clock tick }
  1066.      oldtime:=mem[$0040:$006c];
  1067.      if KBD.Down(kF1) then Help;
  1068.    until KBD.Down(kESC) or ((shipsleft<0) and (boom=0));
  1069.    NoSound;
  1070.    repeat               { post-game loop to keep display active }
  1071.       a:=1;
  1072.       while (high[a]=score[a]) and (a<7) do a:=a+1;
  1073.       if score[a]>high[a] then begin
  1074.          for a:=1 to 7 do high[a]:=score[a];
  1075.          end;
  1076.       MoveRocks;
  1077.       Showscores;
  1078.       MoveEnemy;
  1079.      If Ecount>0 then CrashEnemy;
  1080.       Shoot;
  1081.       MoveDust;
  1082.      if KBD.Down(kF1) then Help;
  1083.       while mem[$0040:$006c]=oldtime do ;
  1084.       oldtime:=mem[$0040:$006c];
  1085.    until KBD.Down(newgame) or KBD.Down(kESC);
  1086. until KBD.Down(kESC);
  1087.    KBD.Done;
  1088.    closegraph;
  1089.    Port[$43] := $43;  {restore normal timer frequency}
  1090.    Port[$40] := 0;
  1091.    Port[$40] := 0;
  1092. end.
  1093.